﻿using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class StoryAction_Move : StoryAction
    {
        private EStoryActionInOut _type;
        private int _point;
        private float _duration;
        private Vector3 _shifting;

        protected override bool OnInitialize(GameObject root, StoryActionData data)
        {
            base.OnInitialize(root, data);
            if (data is StoryActionData_Move rMove)
            {
                this._type = rMove.type;
                this._point = rMove.point;
                this._duration = rMove.duration;
                this._shifting = new Vector3(rMove.shifting.x, rMove.shifting.y, 0);
                return true;
            }
            return false;
        }

        protected override void OnBeforeStart()
        {
            base.OnBeforeStart();
            if (this._type == EStoryActionInOut.Out)
            {
                return;
            }
            var rStartPoint = this.ui.GetSpeakerPoint(this._point);
            this.root.transform.position = rStartPoint.transform.position + this._shifting;
        }

        protected override async UniTask OnStart(CancellationToken cancel)
        {
            await base.OnStart(cancel);
            if (this._type == EStoryActionInOut.Out)
            {
                return;
            }
            var nDynamicPoint = this.GetDynamic<int>(EStoryActionDynamicKey.SelfPoint);
            var rStartPoint = this.ui.GetSpeakerPoint(this._point);
            var rTargetPoint = this.ui.GetSpeakerPoint(nDynamicPoint);
            this.root.transform.position = rStartPoint.transform.position + this._shifting;
            var rTween = DOTween.To(() =>
                {
                    if (this.root)
                    {
                        return this.root.transform.position;
                    }
                    return Vector3.zero;
                },
                (x) =>
                {
                    if (this.root)
                    {
                        this.root.transform.position = x;
                    }
                },
                rTargetPoint.transform.position,
                this._duration
            );
            await rTween.PlayAsync(cancel);
        }

        protected override void OnBeforeEnd()
        {
            base.OnBeforeStart();
            if (this._type == EStoryActionInOut.In)
            {
                return;
            }
            var nDynamicPoint = this.GetDynamic<int>(EStoryActionDynamicKey.SelfPoint);
            var rStartPoint = this.ui.GetSpeakerPoint(nDynamicPoint);
            this.root.transform.position = rStartPoint.transform.position;
        }

        protected override async UniTask OnEnd(CancellationToken cancel)
        {
            await base.OnEnd(cancel);
            if (this._type == EStoryActionInOut.In)
            {
                return;
            }

            var nDynamicPoint = this.GetDynamic<int>(EStoryActionDynamicKey.SelfPoint);
            var rStartPoint = this.ui.GetSpeakerPoint(nDynamicPoint);
            var rTargetPoint = this.ui.GetSpeakerPoint(this._point);
            this.root.transform.position = rStartPoint.transform.position;
            var rTargetPos = rTargetPoint.transform.position + this._shifting;
            var rTween = DOTween.To(() => this.root.transform.position,
                (x) => this.root.transform.position = x,
                rTargetPos,
                this._duration
            );
            await rTween.PlayAsync(cancel);
        }


        public override void OnReset()
        {
            base.OnReset();
            this._type = default;
            this._point = default;
            this._duration = default;
            this._shifting = default;
        }

        public override void Free()
        {
            ClassPool.Put(this);
        }
    }
}